/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package analiseSintatica.Regras.Blocos;

import AnaliseLexicaFinal.EstruturaDeDados.LinkToken;
import analiseSintatica.ErroSintaticoException;
import analiseSintatica.Regras.DeclaracoesIniciais.RegraConst;
import analiseSintatica.Regras.DeclaracoesIniciais.RegraDeclaracao;
import analiseSintatica.Regras.DeclaracoesIniciais.RegraPrototipo;
import analiseSintatica.Regras.DeclaracoesIniciais.RegraTypedef;
import analiseSintatica.Regras.Regra;
import analiseSintatica.estruturadados.NoArvore;

import java.util.LinkedList;

/**
 *
 * @author anderson
 * @date  6:30:10 PM
 */
public class RegraDeclsInicial extends Regra {

    protected static Regra instancia;
//<decls_inicial> ::= {<typedef> | <const> | <prototipo> (";" | <corpo_funcao>) | <declaracao>}
    
    /**
     * Construtor privado necessario ao singleton
     */
    private RegraDeclsInicial(){
        
    }

    /**
     * Retorna a unica instancia dessa classe.
     * @return
     */
    public static RegraDeclsInicial getInstance() {
        if (instancia == null) {
            instancia = new RegraDeclsInicial();
        }
        return (RegraDeclsInicial) instancia;

    }


    @Override
    public NoArvore analisar(LinkedList<LinkToken> listaTokens) throws ErroSintaticoException{
        NoArvore terminalDeclInicial = new NoArvore("<decls_inicial>", false);

        while ( (!listaTokens.get(1).getLexema().equals("main")) && ((RegraTypedef.getInstance().getPrimeiro().contains(listaTokens.getFirst().getToken()))||
        		(RegraConst.getInstance().getPrimeiro().contains(listaTokens.getFirst().getToken()))||
        		(RegraPrototipo.getInstance().getPrimeiro().contains(listaTokens.getFirst().getToken()))||
        		RegraDeclaracao.getInstance().getPrimeiro().contains(listaTokens.getFirst().getToken())
                        ))
                {

            if(RegraTypedef.getInstance().getPrimeiro().contains(listaTokens.getFirst().getToken())){
            	try{
            		terminalDeclInicial.adicionaFilho(RegraTypedef.getInstance().analisar(listaTokens));
            	}catch(ErroSintaticoException e){
            		e.printStackTrace();
            	}
            }
            else if(RegraConst.getInstance().getPrimeiro().contains( listaTokens.getFirst().getToken())){
            	try{
            		terminalDeclInicial.adicionaFilho(RegraConst.getInstance().analisar(listaTokens));
            	}catch(ErroSintaticoException e){
            		e.printStackTrace();
            	}
            }
            else if(RegraPrototipo.getInstance().getPrimeiro().contains( listaTokens.getFirst().getToken())
                    && listaTokens.get(1).getToken().equals("identificador")
                        &&listaTokens.get(2).getLexema().equals("(")){
            	try{

            		terminalDeclInicial.adicionaFilho(RegraPrototipo.getInstance().analisar(listaTokens));
            	}catch(ErroSintaticoException e){
            		e.printStackTrace();
            	}
            	
            	if(listaTokens.getFirst().getLexema().equals(";")){
                    listaTokens.removeFirst();
                    terminalDeclInicial.adicionaFilho(new NoArvore(";", true));
                }
                else{
                	try{
                		terminalDeclInicial.adicionaFilho(RegraCorpoFuncao.getInstance().analisar(listaTokens));
                	}catch(ErroSintaticoException e){
                		e.printStackTrace();
                	}
                }
            }
            else{
            	try{
            		terminalDeclInicial.adicionaFilho(RegraDeclaracao.getInstance().analisar(listaTokens));
            	}catch(ErroSintaticoException e){
            		e.printStackTrace();
            	}
            }
        }
          System.out.println("Terminei decls_inicial");
         return terminalDeclInicial;

    }



    @Override
    protected void setPrimeiro() {
        this.primeiro.add("typedef");
        this.primeiro.add("const");
        this.primeiro.add("char");
        this.primeiro.add("int");
        this.primeiro.add("float");
        this.primeiro.add("boolean");
        this.primeiro.add("void");
        this.primeiro.add("identificador");

//    	this.primeiro = RegraTypedef.getInstance().getPrimeiro();
//    	this.primeiro = getUniao(primeiro, RegraConst.getInstance().getPrimeiro());
//    	this.primeiro = getUniao(primeiro, RegraPrototipo.getInstance().getPrimeiro());
//    	this.primeiro = getUniao(primeiro, RegraDeclaracao.getInstance().getPrimeiro());
//    	this.primeiro = getUniao(primeiro, "e");
    }

    @Override
    protected void setSeguinte() {
        this.seguinte.add("void");
        //s(decls_inicial) = "void" U p(decls_inicial)
//        this.seguinte.add("void");
//        this.seguinte = getUniao(seguinte, this.primeiro);
    }


    
    

}
